package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.ItemTypeStrategy.ItemTypeStrategy;
import com.atguigu.tingshu.user.ItemTypeStrategy.PaidBeanFactory;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    WxMaService wxMaService;
    @Autowired
    WxMaConfig wxMaConfig;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private KafkaService kafkaService;
    @Autowired
    private UserFeignClient userFeignClient;
    @Qualifier("com.atguigu.tingshu.album.AlbumFeignClient")
    @Autowired
    private AlbumFeignClient albumFeignClient;
    @Autowired
    private UserVipServiceMapper userVipServiceMapper;

    @Override
    public String wxLogin(String code) {
        String token = "";
        try {
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            //2.根据微信唯一标识查询用户记录
            String wxOpenId = sessionInfo.getOpenid();
            UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, wxOpenId));
            if (userInfo == null) {
                UserInfo userInfo1 = new UserInfo();
                userInfo1.setWxOpenId(wxOpenId);
                userInfo1.setNickname("听友" + IdUtil.getSnowflakeNextId());//随机昵称
                userInfo1.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
                userInfo1.setIsVip(0);
                userInfoMapper.insert(userInfo1);
                kafkaService.sendMessage(KafkaConstant.QUEUE_USER_REGISTER, String.valueOf(userInfo1.getId()));
                //3.基于用户记录生成Token 将用户令牌存入Redis Key:前缀+token  Value:用户信息UserInfoVo

            }
            token = IdUtil.fastUUID();
            String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
            UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
            redisTemplate.opsForValue().set(loginKey, userInfoVo, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.HOURS);


        } catch (WxErrorException e) {
            log.error("[用户服务]微信登录异常：{}", e);
            throw new RuntimeException(e);
        }
        return token;
    }

    @Override
    public UserInfo getUserInfo(Long userId) {
        UserInfo userInfo = userInfoMapper.selectById(userId);
        return userInfo;
    }

    @Override
    public void updateUser(UserInfoVo userInfoVo, Long userId) {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(userId);
        userInfo.setNickname(userInfoVo.getNickname());
        userInfo.setAvatarUrl(userInfoVo.getAvatarUrl());
        userInfoMapper.updateById(userInfo);

    }

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Autowired
    private UserPaidTrackMapper userpaidTrackMapper;
    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;

    @Override
    public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> needcheckTrackIds) {
        //根据专辑Id查询该专辑是否购买
        QueryWrapper<UserPaidAlbum> eq = new QueryWrapper<UserPaidAlbum>()
                .eq("user_id", userId)
                .eq("album_id", albumId);

        Long buy = userPaidAlbumMapper.selectCount(eq);
        //购买了专辑直接所有声音列表设置ID为1
        HashMap<Long, Integer> resultMa = new HashMap<>();
        if (buy > 0) {
            for (Long needcheckTrackId : needcheckTrackIds) {
                resultMa.put(needcheckTrackId, 1);

            }
        }
        //未购买专辑查询声音列表是否购买
        else {
            QueryWrapper<UserPaidTrack> queryWrapper = new QueryWrapper<UserPaidTrack>()
                    .eq("user_id", userId)
                    .in("track_id", needcheckTrackIds);
            List<UserPaidTrack> userPaidTracks = userpaidTrackMapper.selectList(queryWrapper);
            List<Long> collect = userPaidTracks.stream().map((track) -> {
                return track.getTrackId();
            }).collect(Collectors.toList());
            // 遍历需要检查的声音列表，判断每个声音是否已购买
            for (Long needcheckTrackId : needcheckTrackIds) {
                // 初始化标志位，用于标记当前声音是否在已购买声音列表中
                boolean found = false;
                // 遍历已购买的声音列表
                for (Long l : collect) {
                    // 检查当前已购买声音的 ID 是否与需要检查的声音 ID 相等
                    if (l.equals(needcheckTrackId)) {
                        // 若相等，说明该声音已购买，将标志位设为 true
                        found = true;
                        // 找到后跳出内层循环，无需继续比较
                        break;
                    }
                }
                // 根据标志位的值，将声音 ID 及其对应的购买状态（1 表示已购买，0 表示未购买）存入结果 Map 中
                resultMa.put(needcheckTrackId, found ? 1 : 0);
            }
            //未购买的声音列表设置ID为0
            //已经购买的声音列表设置ID为1

        }
        return resultMa;
    }

    @Override
    public Result<List<VipServiceConfig>> findAll() {
        return Result.ok(vipServiceConfigMapper.findAll());
    }

    @Override
    public Boolean getalbumisPaidorNot(Long userId, Long albumId) {
        QueryWrapper<UserPaidAlbum> eq = new QueryWrapper<UserPaidAlbum>()
                .eq("user_id", userId)
                .eq("album_id", albumId);
        return userPaidAlbumMapper.selectOne(eq) != null;

    }

    @Override
    public Boolean getUserIsVipOrNot(Long userId, Long albumId) {

        UserInfo userInfo = userInfoMapper.selectById(userId);

        return userInfo.getIsVip() == 1;

    }

    @Override
    public List<Long> getuserIsPaidTrackIdList(Long userId, Long albumId, List<Long> needcheckIdList) {
//先查看专辑是否已经购买
        if (getalbumisPaidorNot(userId, albumId)) {
            return null;
        } else {
            List<Long> hasbuyList = userpaidTrackMapper.selectList(new QueryWrapper<UserPaidTrack>()
                            .eq("user_id", userId).
                            eq("album_id", albumId).
                            in("track_id", needcheckIdList)).
                    stream().map(UserPaidTrack::getTrackId).toList();
            return needcheckIdList.stream().filter(id -> !hasbuyList.contains(id)).toList();
        }

    }
@Autowired
    PaidBeanFactory paidBeanFactory;
    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public void addUserPaidRecord(Long userId, UserPaidRecordVo userPaidRecordVo) {
        String orderNo = userPaidRecordVo.getOrderNo();

        String itemType = userPaidRecordVo.getItemType();
        ItemTypeStrategy bean = paidBeanFactory.getBean(itemType);
        if (bean == null) {
            throw new GuiguException(400, "订单类型错误");
        } else {
            bean.SavePaidRecord(userPaidRecordVo);
            log.info("订单类型为：{}", itemType);
        }

    }
       /* List<Long> itemIdList = userPaidRecordVo.getItemIdList();//项目id列表

        if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(itemType)) {
            Long albumId = itemIdList.get(0);

            //购买专辑
            Boolean bolean = userFeignClient.getalbumisPaidorNot(albumId).getData();
            if (bolean) {
                //如果购买过,直接报错显示已购买
                return;
            }
            UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
            userPaidAlbum.setUserId(userId);
            userPaidAlbum.setAlbumId(itemIdList.get(0));
            userPaidAlbum.setOrderNo(orderNo);
            userPaidAlbumMapper.insert(userPaidAlbum);

        } else if (SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(itemType)) {
            QueryWrapper<UserPaidTrack> trackInfoQueryWrapper = new QueryWrapper<>();
            trackInfoQueryWrapper.eq("order_no", userPaidRecordVo.getOrderNo());
            Long l = userpaidTrackMapper.selectCount(trackInfoQueryWrapper);
            if (l > 0) {
                return;
            }
            for (Long trackId : itemIdList) {
                AlbumInfo data = albumFeignClient.getAlbumInfobytrackId(trackId).getData();
                Long albumId = data.getId();
                UserPaidTrack userPaidTrack = new UserPaidTrack();
                userPaidTrack.setUserId(userId);

                userPaidTrack.setAlbumId(albumId);
                userPaidTrack.setOrderNo(orderNo);
                userPaidTrack.setTrackId(trackId);
                userpaidTrackMapper.insert(userPaidTrack);
            }


            //购买声音
        } else if (SystemConstant.ORDER_ITEM_TYPE_VIP.equals(itemType)) {
            //购买VIP
            QueryWrapper<UserVipService> vipServiceQueryWrapper = new QueryWrapper<>();
            vipServiceQueryWrapper.eq("order_no", orderNo);
            Long l = userVipServiceMapper.selectCount(vipServiceQueryWrapper);
            if (l > 0) {
                return;
            }
            UserVipService userVipService = new UserVipService();
            userVipService.setUserId(userId);
            userVipService.setOrderNo(orderNo);

            UserInfo userInfo = this.getUserInfo(userId);
            Date vipExpireTime = userInfo.getVipExpireTime();
            VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(itemIdList.get(0));
            Integer serviceMonth = vipServiceConfig.getServiceMonth();
            if (userInfo.getIsVip() == 1 && vipExpireTime.after(new Date())) {
                //如果是VIP
                userVipService.setStartTime(vipExpireTime);

                DateTime dateTime = DateUtil.offsetMonth(vipExpireTime, serviceMonth);
                userVipService.setExpireTime(dateTime);

            } else {
                userVipService.setStartTime(new Date());
                DateTime dateTime = DateUtil.offsetMonth(new Date(), serviceMonth);
                userVipService.setExpireTime(dateTime);

            }
            userVipServiceMapper.insert(userVipService);
            userInfo.setIsVip(1);
            userInfo.setVipExpireTime(userVipService.getExpireTime());
            userInfoMapper.updateById(userInfo);


        } else {
            throw new GuiguException(400, "订单类型错误");
        }


    }*/

}
